package jp.sourceforge.akjrcp.snack;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import jp.sourceforge.akjrcp.ui.draw2d.GraphLabelProvider;
import jp.sourceforge.akjrcp.ui.draw2d.SimpleGraphMemoryPainterDraw2D;
import jp.sourceforge.akjrcp.ui.draw2d.TimeBasedFigure;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.StackLayout;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;

/*
 * show list of subtitle info
 */
public  class PitchViewFigure extends TimeBasedFigure{
	public static Log log=LogFactory.getLog(PitchViewFigure.class);
	
	 private int dotSize=4;
        private int offsetY=0;//ignore y
        private int offsetX=-dotSize;//draw start at
        
       
        private RGB lineColor=ColorConstants.cyan.getRGB();
        private RGB black=ColorConstants.black.getRGB();
        private ESPS[] espses;
        private double espsStarted=PitchExecuter.SKIPPED_TIME;
        private double espsTime;
        
       
        private int maxPitch=2400;
        private int minPitch=0;
        private int canvasHeight=512;//same as image height;
       
     
        public double getEspsStarted() {
			return espsStarted;
		}


		public void setEspsStarted(double espsStarted) {
			this.espsStarted = espsStarted;
		}


		public double getEspsTime() {
			return espsTime;
		}


		public void setEspsTime(double espsTime) {
			this.espsTime = espsTime;
		}


		/**
         * @param arg0
         * @param arg1
         */
        public PitchViewFigure(int arg0, int arg1,double splitFrame) {
            super(arg0, arg1,splitFrame);
            this.setLayoutManager(new StackLayout());
            //this.add(new PitchMemoryFigure());//hz
        }
        
        
       public void updateScale(){
    	  
       }
        
       public int calculatePitchToY(double pitch){
    	   //double per=((double)this.getClientArea().height-marginTop-marginBottom)/(maxPitch-minPitch);
    	   double per=(double)canvasHeight/maxPitch;
    	   return this.getClientArea().height-marginBottom-(int)(per*(pitch-minPitch));
       }
       

        private int minMeasurement=100;//TODO handle them
        public void paintFigure(Graphics g){
        	//log.infopitch:"+this.getClientArea());
        	int tmpVline=80;
            if(espses!=null){
            	double time=espsStarted;
            g.setBackgroundColor(new Color(null,lineColor));
            g.setForegroundColor(new Color(null,lineColor));
            int scrolled=getParent().getBounds().x;//parent view
            for(int i=0;i<espses.length;i++){
            	ESPS esps=espses[i];
            	int dx=calculateTimeToX(time);
            	if(esps.getMeasurements()<minMeasurement){
            		 g.setForegroundColor(new Color(null,black));
            	}else{
            		 g.setForegroundColor(new Color(null,lineColor));
            	}
            	int mh=(int) (esps.getMeasurements()/100);
            	//draw level
            	g.drawRectangle(scrolled+dx-dotSize/2,tmpVline-dotSize/2,dotSize,mh);
            	
            	//not support yet
            	//int mc=(int) (esps.getCorrelation()*100);
            	//g.drawRectangle(scrolled+dx-dotSize/2,tmpVline+mc,dotSize,mc);
            	
            	if(esps.getPitch()>minPitch && esps.getPitch()<maxPitch){
            	
            		int dy=calculatePitchToY(esps.getPitch());
            		//log.info(dx+","+dy+" time="+time);
            		
            		g.fillRectangle(scrolled+dx-dotSize/2,dy-dotSize/2,dotSize,dotSize);
            	}
            	time+=espsTime;
            }
            }
        }


		


		public RGB getLineColor() {
			return lineColor;
		}


		public void setLineColor(RGB lineColor) {
			this.lineColor = lineColor;
		}


		public int getOffsetX() {
			return offsetX;
		}


		public void setOffsetX(int offsetX) {
			this.offsetX = offsetX;
		}


		public int getOffsetY() {
			return offsetY;
		}


		public void setOffsetY(int offsetY) {
			this.offsetY = offsetY;
		}
		
		//
		private int marginBottom=0;
    	private int marginTop=128;
    	
	
    	  
		  public static class PitchMemoryFigure extends Figure{
			  private int graphGrid=100;	//per grid
			  private int maxPitch=2400;	//for 48000khz wav
			  private int minPitch=0;
			  
			   private int minLabelPitch=80;
		        private int maxLabelPitch=1000;
		        
		        private SimpleGraphMemoryPainterDraw2D painter;
		        
		        public PitchMemoryFigure(){
		            painter = new  SimpleGraphMemoryPainterDraw2D();
		            
		            painter.setMainGridPixel(16);
		            painter.setSubGridPixel(12);
		            
		            painter.setVerticalGraph(true);
		            painter.setGraphPlus(false);
		            painter.setGridPlus(true);
		            painter.setLabelProvider(new LabelProvider());
		            painter.setLineColor(ColorConstants.gray);
		        }
		        public void paintFigure(Graphics g) {
		        	//log.info("memoryfigure:"+g.getClip(this.getClientArea()));
		        	//should update value
		        	//int dh=this.getClientArea().height-marginTop-marginBottom;
		        	
		        	//for not avoid header memory. 
		        	//g.clipRect(new Rectangle(0,40,this.getClientArea().width,this.getClientArea().height));
		        	
		        	int dh=512;//fit image height
		            int step=(maxPitch-minPitch)/graphGrid;
		            
		            double perMain=(double)dh/step;
		            painter.setPerMain(perMain);
		            painter.draw(g,this.getClientArea().x,this.getClientArea().y+this.getClientArea().height,dh);
		            
		            int labelMax=this.getClientArea().y+this.getClientArea().height-(int) (perMain*(maxLabelPitch/graphGrid))-1;
		            g.drawLine(0, labelMax, 72, labelMax);
		            
		            int labelMin=this.getClientArea().y+this.getClientArea().height-(int) (perMain*minLabelPitch/graphGrid)-1;
		            g.drawLine(0, labelMin, 72, labelMin);
		         }
		        
		       
		        public SimpleGraphMemoryPainterDraw2D getPainter() {
		            return painter;
		        }
		        public void setPainter(SimpleGraphMemoryPainterDraw2D painter) {
		            this.painter = painter;
		        }
				public int getMaxPitch() {
					return maxPitch;
				}
				public void setMaxPitch(int maxPitch) {
					this.maxPitch = maxPitch;
				}
				public int getMinPitch() {
					return minPitch;
				}
				public void setMinPitch(int minPitch) {
					this.minPitch = minPitch;
				}
				public int getMinLabelPitch() {
					return minLabelPitch;
				}
				public void setMinLabelPitch(int minLabelPitch) {
					this.minLabelPitch = minLabelPitch;
				}
				public int getMaxLabelPitch() {
					return maxLabelPitch;
				}
				public void setMaxLabelPitch(int maxLabelPitch) {
					this.maxLabelPitch = maxLabelPitch;
				}
		    }
		  
		  
		    public static class LabelProvider implements GraphLabelProvider{
		    
		        public String getLabel(SimpleGraphMemoryPainterDraw2D painter, int index) {
		        	String v=""+index;
		        	if(v.length()<2){
		        		v="0"+v;
		        	}
		        	if(v.equals("01") || v.equals("10") || v.equals("20")){
		        		v+=" khz";
		        	}
		        	 return v;
		           // return ""+(minPitch+index*graphGrid);//100 is pitch grid
		        }
		        
		    }


			public ESPS[] getEspses() {
				return espses;
			}


			public void setEspses(ESPS[] espses) {
				this.espses = espses;
				
			}


			public int getMaxPitch() {
				return maxPitch;
			}


			public void setMaxPitch(int maxPitch) {
				this.maxPitch = maxPitch;
			}


			public int getMinMeasurement() {
				return minMeasurement;
			}


			public void setMinMeasurement(int minMeasurement) {
				this.minMeasurement = minMeasurement;
			}
        
    }